Poker sorting hurts me
So, today is poker hand sorting day, huh. Simplified, but still. I faintly remember doing something similar ages ago, and having immense trouble, something was always slightly off.
And guess what, that happened again! And it wasn't even a logic error!
// what I had
const ORDER: &[u8] = b"23456789JTQKA";
// what's correct
const ORDER: &[u8] = b"23456789TJQKA";
See if you can spot the mistake. 'cause I sure couldn't for an uncomfortably long amount of time...
Anyway, as for code, it's conceptually relatively easy. For each hand, just create a sort key. Sort the hands. Do some multiplying and summing.
The only interesting observation, in my opinion, is that you don't need to try out any alternatives with the jokers. The correct choice is always treating them as whatever you already have the most of.
fn hand_value(hand: [u8; 5], joker: bool) -> (u8, [usize; 5]) {
// Count how much of which card we have.
let mut joker_count = 0;
let mut counts = vec![];
let mut seen = vec![];
for c in hand {
if joker && c == b'J' {
joker_count += 1;
} else if let Some(p) = seen.iter().position(|&card| c == card) {
counts[p] += 1;
} else {
seen.push(c);
counts.push(1);
}
}
// Adding the joker count to the highest count will always produce the best hand.
counts.sort_unstable();
if let Some(c) = counts.last_mut() {
*c += joker_count;
} else {
counts.push(joker_count);
}
// Determine hand strength based purely on card counts. Because we sorted earlier, we can do
// direct slice matching.
let strength = match counts.as_slice() {
[1, 1, 1, 1, 1] => 1,
[1, 1, 1, 2] => 2,
[1, 2, 2] => 3,
[1, 1, 3] => 4,
[2, 3] => 5,
[1, 4] => 6,
[5] => 7,
_ => 0,
};
// Convert raw cards into their strength.
let order = if joker { JOKER_ORDER } else { ORDER };
let card_value = |c| order.iter().position(|&b| c == b).unwrap();
(strength, hand.map(card_value))
}
This is the entire heart of my solution. You can then just sort{_unstable}_by_key
with this as the key, and you're pretty much done. I'm happy with the direct slice matching to determine what kind of hand it is; seems clearer to me than some sort of series of conditions.
But mostly I'm just glad to be done with this, lol.